package com.grantheath.erebus.model 
{
	import com.grantheath.erebus.model.enum.notifications.ErebusInitializationNotifications;
	import com.grantheath.erebus.model.interfaces.IErebusPageLoaderProxy;
	import com.grantheath.erebus.model.enum.notifications.ErebusPageNotifications;
	import com.grantheath.erebus.model.enum.notifications.ErebusPageLoaderNotifications;
	import com.grantheath.erebus.model.enum.names.ErebusProxyNames;
	import com.grantheath.erebus.view.interfaces.IErebusPage;
	import com.grantheath.erebus.model.interfaces.IErebusPageLoader;
	import com.grantheath.erebus.model.interfaces.IErebusPageNode;
	import com.grantheath.erebus.model.helpers.ErebusLoadEvent;

	import org.puremvc.as3.patterns.proxy.Proxy;

	/**
	 * @author grantheath
	 */
	public class ErebusPageLoaderProxy extends Proxy implements IErebusPageLoaderProxy 
	{
		private var _loadedPage : IErebusPage;

		public function ErebusPageLoaderProxy()
		{
			super(ErebusProxyNames.PAGE_LOADER_PROXY);
		}

		override public function onRegister() : void
		{
			sendNotification(ErebusInitializationNotifications.INITIALIZE_PROXIES);
		}

		public function loadPage(pageNode : IErebusPageNode) : void
		{
			var pageLoaderClass : Class = pageNode.pageLoaderClass;
			
			pageNode.pageLoader = new pageLoaderClass();
			pageNode.pageLoader.addEventListener(ErebusLoadEvent.LOAD_OPEN, onPageLoadOpen);
			pageNode.pageLoader.addEventListener(ErebusLoadEvent.LOAD_COMPLETE, onPageLoadComplete);
			pageNode.pageLoader.addEventListener(ErebusLoadEvent.LOAD_ERROR, onPageLoadError);
			pageNode.pageLoader.addEventListener(ErebusLoadEvent.LOAD_PROGRESS, onPageLoadProgress);
			pageNode.pageLoader.loadPage(pageNode);
		}
		
		public function removePageLoadEvents(pageNode : IErebusPageNode) : void
		{
			if(pageNode.pageLoader){
				pageNode.pageLoader.removeEventListener(ErebusLoadEvent.LOAD_OPEN, onPageLoadOpen);
				pageNode.pageLoader.removeEventListener(ErebusLoadEvent.LOAD_COMPLETE, onPageLoadComplete);
				pageNode.pageLoader.removeEventListener(ErebusLoadEvent.LOAD_ERROR, onPageLoadError);
				pageNode.pageLoader.removeEventListener(ErebusLoadEvent.LOAD_PROGRESS, onPageLoadProgress);
			}
		}
		
		//EVENT LISTENERS
		private function onPageLoadProgress(event : ErebusLoadEvent) : void
		{
			var loader : IErebusPageLoader = event.target as IErebusPageLoader;
			var pageNode : IErebusPageNode = loader.pageNode;
			
			sendNotification(ErebusPageLoaderNotifications.PAGE_LOAD_PROGRESS, pageNode);
		}
		
		private function onPageLoadComplete(event : ErebusLoadEvent) : void
		{
			var loader : IErebusPageLoader = event.target as IErebusPageLoader;
			var pageNode : IErebusPageNode = loader.pageNode;
			
			_loadedPage = loader.loadedPage;
			if(!pageNode.page){
				//only assign the loaded page to the tree node if the nodes value == null
				//sometimes a load can start, but the transitition is interrupted before the load is complete
				//in some instances this can lead to a page that has been reloaded and does not need to bee assigned to the tree node
				pageNode.page = loadedPage;
				sendNotification(ErebusPageNotifications.PAGE_INITIALIZED, pageNode);
			}
			removePageLoadEvents(pageNode);
			sendNotification(ErebusPageLoaderNotifications.PAGE_LOAD_COMPLETE, pageNode);
		}

		private function onPageLoadError(event : ErebusLoadEvent) : void
		{
			var loader : IErebusPageLoader = event.target as IErebusPageLoader;
			var pageNode : IErebusPageNode = loader.pageNode;
			
			sendNotification(ErebusPageLoaderNotifications.PAGE_LOAD_ERROR, pageNode);
		}

		private function onPageLoadOpen(event : ErebusLoadEvent) : void
		{
			var loader : IErebusPageLoader = event.target as IErebusPageLoader;
			var pageNode : IErebusPageNode = loader.pageNode;
			
			sendNotification(ErebusPageLoaderNotifications.PAGE_LOAD_PROGRESS, pageNode);
		}
		
		//GETTERS OR SETTERS
		public function get loadedPage() : IErebusPage
		{
			return _loadedPage;
		}
		
		public function set loadedPage(loadedPage : IErebusPage) : void
		{
			_loadedPage = loadedPage;
		}
	}
}